package cn.turboinfo.fuyang.api.domain.admin.usecase.company;

import cn.turboinfo.fuyang.api.domain.common.service.company.HousekeepingCompanyAuditRecordService;
import cn.turboinfo.fuyang.api.domain.common.service.company.HousekeepingCompanyService;
import cn.turboinfo.fuyang.api.domain.common.service.user.SysUserService;
import cn.turboinfo.fuyang.api.domain.common.service.user.UserCredentialService;
import cn.turboinfo.fuyang.api.domain.common.service.user.UserLoginService;
import cn.turboinfo.fuyang.api.domain.common.service.user.UserTypeRelService;
import cn.turboinfo.fuyang.api.domain.common.usecase.AbstractUseCase;
import cn.turboinfo.fuyang.api.domain.util.SecurityUtils;
import cn.turboinfo.fuyang.api.entity.admin.enumeration.login.AdminLoginOperation;
import cn.turboinfo.fuyang.api.entity.common.enumeration.audit.AuditStatus;
import cn.turboinfo.fuyang.api.entity.common.enumeration.company.CompanyStatus;
import cn.turboinfo.fuyang.api.entity.common.enumeration.user.LoginNameType;
import cn.turboinfo.fuyang.api.entity.common.exception.company.HousekeepingCompanyException;
import cn.turboinfo.fuyang.api.entity.common.pojo.company.HousekeepingCompany;
import cn.turboinfo.fuyang.api.entity.common.pojo.company.HousekeepingCompanyAuditRecordCreator;
import cn.turboinfo.fuyang.api.entity.common.pojo.company.HousekeepingCompanyUpdater;
import cn.turboinfo.fuyang.api.entity.common.pojo.user.SysUser;
import cn.turboinfo.fuyang.api.entity.common.pojo.user.SysUserCreator;
import cn.turboinfo.fuyang.api.entity.common.pojo.user.UserLogin;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.base.enums.EnableStatus;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author gadzs
 * @description 家政企业审核usecase
 * @date 2023/1/29 16:26
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class HousekeepingCompanyReviewedUseCase extends AbstractUseCase<HousekeepingCompanyReviewedUseCase.InputData, HousekeepingCompanyReviewedUseCase.OutputData> {
    private final HousekeepingCompanyService housekeepingCompanyService;

    private final UserLoginService userLoginService;

    private final SysUserService sysUserService;

    private final UserTypeRelService userTypeRelService;

    private final UserCredentialService userCredentialService;

    private final HousekeepingCompanyAuditRecordService housekeepingCompanyAuditRecordService;

    @Override
    protected OutputData doAction(InputData inputData) {
        Long id = inputData.getId();
        val auditorId = inputData.getUserId();

        val company = housekeepingCompanyService.getByIdEnsure(id);
        if (company.getStatus() != CompanyStatus.REGISTER) {
            throw new HousekeepingCompanyException("数据状态不是待审核，操作失败");
        }

        String loginName = company.getContactNumber();

        // 从登录方式检查登记的手机号用户是否存在
        Long userId;
        List<UserLogin> loginList = userLoginService.findByLoginNameAndLoginNameType(loginName, LoginNameType.PHONE_NUM);
        if (loginList.isEmpty()) {
            log.error("用户不存在, 自动创建, loginName={}", loginName);
            // 创建用户
            SysUserCreator.Builder builder = SysUserCreator.builder()
                    .withMobile(loginName)
                    .withUsername(loginName)
                    .withStatus(EnableStatus.ENABLED)
                    .withLoginOperation(AdminLoginOperation.MODIFY_PASSWORD);
            // 设置初始密码为法人身份证后六位
            SysUser sysUser = sysUserService.save(builder.build(), null);

            createCompanyRel(sysUser.getId(), company);
        } else {
            // 用户已存在, 检查是否已有消费者关联
            userId = loginList.get(0).getUserId();
            if (!userTypeRelService.hasCompanyRel(userId, company.getId())) {
                createCompanyRel(userId, company);
            }
        }

        //更新状态
        HousekeepingCompanyUpdater.Builder builder = HousekeepingCompanyUpdater.builder(id);

        // 生成 appId appSecret
        builder
                .withStatus(CompanyStatus.REVIEWED)
                .withReviewUserId(inputData.getUserId())
                .withReviewTime(LocalDateTime.now())
                .withAppId(SecurityUtils.generateAppId(id))
                .withAppSecret(SecurityUtils.generateAppSecret());

        HousekeepingCompany housekeepingCompany = housekeepingCompanyService.review(builder.build());
        val auditorUser = sysUserService.getByIdEnsure(auditorId);

        // 更新审核记录
        {
            HousekeepingCompanyAuditRecordCreator housekeepingCompanyAuditRecord = HousekeepingCompanyAuditRecordCreator.builder()
                    .withCompanyId(housekeepingCompany.getId())
                    .withAuditStatus(AuditStatus.REVIEWED)
                    .withUserId(auditorId)
                    .withUserName(auditorUser.getUsername())
                    .withRemark("审核通过")
                    .build();
            housekeepingCompanyAuditRecordService.save(housekeepingCompanyAuditRecord);
        }

        return OutputData.builder()
                .id(housekeepingCompany.getId())
                .build();
    }

    private void createCompanyRel(Long userId, HousekeepingCompany company) {
        // 如果之前没设置过密码 设置初始密码为法人身份证后六位
        if (userCredentialService.findUserDefault(userId).isEmpty()) {
            userCredentialService.save(userId, StringUtils.substring(company.getLegalPersonIdCard(), -6));
        }
        // 创建相应的关联
        userTypeRelService.createCompanyRel(userId, company.getId());
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InputData extends AbstractUseCase.InputData {

        @NotNull(
                message = "id不能为空"
        )
        private Long id;

        @NotNull(message = "审核用户ID不能为空")
        private Long userId;
    }

    @Getter
    @Setter
    @Builder
    public static class OutputData extends AbstractUseCase.OutputData {
        private Long id;
    }

}
